package com.motong.gongdan.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.motong.gongdan.entity.*;
import com.motong.gongdan.enums.ObjectType;
import com.motong.gongdan.mapper.MissionMapper;
import com.motong.gongdan.util.ColumnUtils;
import com.motong.gongdan.util.StringUtil;
import com.motong.gongdan.util.TimeUtil;
import com.motong.gongdan.vo.H5Vo.common.GroupCountVo;
import com.motong.gongdan.vo.H5Vo.customfield.RadioOptionVo;
import com.motong.gongdan.vo.H5Vo.mission.query.H5MissionListQuery;
import com.motong.gongdan.vo.resp.MissionListResp;
import com.motong.gongdan.vo.system.otherVo.CustomFieldVo;
import com.motong.gongdan.vo.system.otherVo.MissionListVo;
import com.motong.gongdan.vo.system.processSop.CollectionDataVo;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@Service
public class MissionService extends ServiceImpl<MissionMapper, Mission> {

    @Resource
    private WorkOrderService workOrderService;

    @Resource
    private UserService userService;

    @Resource
    private CustomFieldService customFieldService;

    @Resource
    MongoTemplate mongoTemplate;

    @Resource
    private ScreenPlanService screenPlanService;


    @Resource
    private MissionService missionService;


    /**
     * 根据工单编码获取分组数量
     *
     * @param workOrderCodes 工单编码集合
     * @return 工单编码(数量)信息
     */
    public List<Map<String, Object>> getCountGroupByWorkOrder(Set<String> workOrderCodes) {
        return this.baseMapper.getCountGroupByWorkOrder(workOrderCodes);
    }

    /**
     * 获取任务列表(默认剔除状态为0的数据)
     *
     * @param mergeSearchResult 查询条件
     * @return 任务列表
     */
    public Page<MissionListResp> getH5MissionList(Page<Mission> page, H5MissionListQuery mergeSearchResult, User currentUser, boolean isH5) {

        Page<MissionListResp> data = this.baseMapper.getH5MissionList(page, mergeSearchResult, isH5);

        List<MissionListResp> records = data.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            // 工单，工序对应的自定义字段工具
            ColumnUtils orderColumnUtils = new ColumnUtils(customFieldService, ObjectType.workOrder.getCode());
            ColumnUtils processColumnUtils = new ColumnUtils(customFieldService, ObjectType.processes.getCode());
            // 获取工单自定义地段 code 自定义字段的映射
            Set<String> workOrderIds = records.stream().map(MissionListResp::getWorkOrderCode).collect(Collectors.toSet());
            Map<String, List<CustomFieldVo>> workOrderCodeCustomFieldMap = new HashMap<>(workOrderIds.size());
            List<WorkOrder> workOrders = workOrderService.list(new LambdaQueryWrapper<WorkOrder>().in(WorkOrder::getCode, workOrderIds).isNotNull(WorkOrder::getOther));
            workOrders.forEach(i -> workOrderCodeCustomFieldMap.put(i.getCode(), StringUtils.hasLength(i.getOther()) ? orderColumnUtils.getCuColumnsByJsonArray(i.getOther()) : null));
            records.forEach(i -> {
                if (StringUtil.isNotBlank(i.getDistributionList())) {
                    List<String> userIds = Arrays.asList(i.getDistributionList().split(","));
//                    i.setDistribute(userIds.contains(currentUser.getId().toString()));
                    List<User> names = userService.listByIds(userIds);
                    String name = names.stream().map(User::getName).collect(Collectors.joining(","));
                    i.setDistributionName(name);
                }
                i.setWorkOrderCustomFieldVos(workOrderCodeCustomFieldMap.get(i.getWorkOrderCode()));
                // 如果是自己创建或所有或在给定部门下则为true
                boolean havePermission = false;
                //部门 用户权限判断(有一即可)
                if (StringUtils.hasLength(i.getPermissionsDep()) && StringUtils.hasLength(currentUser.getDepId())) {
                    havePermission = CollectionUtils.containsAny(Arrays.asList(i.getPermissionsDep().split(",")), Arrays.asList(currentUser.getDepId().split(",")));
                }
                if (!havePermission && StringUtils.hasLength(i.getProcessPermissions())) {
                    havePermission = CollectionUtils.containsAny(Arrays.asList(i.getProcessPermissions().split(",")), Arrays.asList(currentUser.getName(), "所有人"));
                }
                i.setDistributionFlag(havePermission);
                i.setIsDelay(0);
                if (!TimeUtil.afterNow(i.getEndTime()) && i.getProcessState() == 1) {
                    i.setIsDelay(1);
                }
                if (StringUtil.isNotBlank(i.getProcessOther())) {
                    i.setCustomFieldVos(processColumnUtils.getCuColumnsByJsonArray(i.getProcessOther()));
                }
                if (StringUtil.isNotBlank(i.getProcessCollectionData())) {
                    i.setProcessCollectionDataList(JSONUtil.toList(i.getProcessCollectionData(), CollectionDataVo.class));
                }
            });
        }

        return data;
    }

    /**
     * 获取分类统计数量
     *
     * @param mergeSearchResult 查询条件
     * @return 类型数量映射
     */
    public List<GroupCountVo> getTypeCountMap(H5MissionListQuery mergeSearchResult, String groupColumn, String cnName, boolean isH5) {

        Map<String, String> typeValueNameMap = new HashMap<>(10);
        String prefix = "b.";
        boolean isSortByValue = false;
        switch (groupColumn) {
            case "processState":
                typeValueNameMap.put("0", "未开始");
                typeValueNameMap.put("1", "执行中");
                typeValueNameMap.put("2", "已结束");
                mergeSearchResult.setProcessState(null);
                isSortByValue = true;
                break;
            case "processName":
                prefix = "d.";
                groupColumn = "name";
                mergeSearchResult.setProcessName(null);
                break;
            case "distributionState":
                prefix = "";
                typeValueNameMap.put("0", "未分配");
                typeValueNameMap.put("1", "已分配");
                mergeSearchResult.setDistributionState(null);
                isSortByValue = true;
                groupColumn = "IF(ISNULL(b.distribution_list) OR b.distribution_list = '','0','1')";
                break;
        }
        if ("distributionName".equals(groupColumn)) {
            List<User> userList = userService.list(new LambdaQueryWrapper<User>().eq(User::getState, 0));
            List<GroupCountVo> groupCountVos = new ArrayList<>();
            userList.forEach(i -> {
                GroupCountVo groupCountVo = new GroupCountVo().setOptionName(i.getAccount()).setOptionValue(i.getId().toString()).setTypeName(cnName);
                mergeSearchResult.setDistribution(i.getId().toString());
                List<GroupCountVo> typeCountMap = this.baseMapper.getTypeCountMap(mergeSearchResult, null, isH5);
                groupCountVo.setOptionNum(CollectionUtils.isEmpty(typeCountMap) ? 0 : typeCountMap.get(0).getOptionNum());
                groupCountVos.add(groupCountVo);
            });
            return groupCountVos;
        }

        List<GroupCountVo> typeCountData = this.baseMapper.getTypeCountMap(mergeSearchResult, prefix + StrUtil.toUnderlineCase(groupColumn), isH5);
        typeCountData.forEach(i -> {
            i.setTypeName(cnName);
            if (!typeValueNameMap.isEmpty()) {
                i.setOptionName(typeValueNameMap.get(i.getOptionValue()));
                typeValueNameMap.remove(i.getOptionValue());
            } else {
                i.setOptionName(i.getOptionValue());
            }
        });
        typeValueNameMap.forEach((k, v) -> {
            typeCountData.add(new GroupCountVo().setOptionNum(0L).setTypeName(cnName).setOptionName(v).setOptionValue(k));
        });
        if (isSortByValue) {
            return typeCountData.stream().sorted(Comparator.comparingInt(f -> Integer.parseInt(f.getOptionValue()))).collect(Collectors.toList());
        }
        return typeCountData;
    }

    /**
     * 缓存任务自定义字段
     */
    public void cacheCustomToMongo(Mission mission) {
        if (StringUtils.hasLength(mission.getProcessOther())) {
            Mission missionMongo = new Mission();
            missionMongo.setId(mission.getId());
            missionMongo.setCustomFieldMess(JSONArray.parseArray(mission.getProcessOther()));
            mongoTemplate.save(missionMongo);
        }
    }

    /**
     * 更新状态
     *
     * @return 错误信息  正确为null
     */
    public String changeStatus(Mission newMission, Mission oriMission) {
        if (Objects.nonNull(newMission.getProcessState()) && !newMission.getProcessState().equals(oriMission.getProcessState())) {
            Integer oriState = oriMission.getProcessState();
            switch (newMission.getProcessState()) {
                case 0:
                    if (oriState != 1) {
                        return "任务非执行中状态不能回退至未开始";
                    }
                    newMission.setActualStartTime(null);
                    break;
                case 1:
                    if (oriState == 2) {
                        newMission.setActualEndTime(null);
                    }
                    newMission.setActualStartTime(Optional.ofNullable(oriMission.getActualStartTime()).orElse(new Date()));
                    break;
                case 2:
                    newMission.setActualStartTime(Optional.ofNullable(oriMission.getActualStartTime()).orElse(new Date()));
                    newMission.setActualEndTime(new Date());
                    break;
            }
        }
        return null;
    }


    /**
     * 获取任务二级分组数量
     *
     * @param screenPlanId      筛选方案id
     * @param mergeSearchResult 查询条件
     * @return 二级分组数量统计
     */
    public List<GroupCountVo> getSecondGroupTypeCount(Integer screenPlanId, H5MissionListQuery mergeSearchResult,boolean isH5) {
        List<GroupCountVo> typeCountData = new ArrayList<>();
        if (Objects.nonNull(screenPlanId)) {
            ScreenPlan screenPlan = screenPlanService.getById(screenPlanId);
            String secondGroup = screenPlan.getSecondGroup();
            Map<String, String> cnEnMap = ColumnUtils.BASE_COLUMN_CN_EN_MAP.getOrDefault(ObjectType.mission.getCode(), Collections.emptyMap());
            String enName = cnEnMap.get(secondGroup);
            if (Objects.nonNull(enName) || "分配状态".equals(secondGroup)) {
                String resetEnName = ("分配状态".equals(secondGroup) ? "distributionState" : enName);
                mergeSearchResult.setSecondGroupColumnName("distributionName".equals(enName) ? "distribution" : resetEnName);
                typeCountData.addAll(missionService.getTypeCountMap(mergeSearchResult, resetEnName, secondGroup, false));
            } else {
                // 自定义字段分组
                mergeSearchResult.setSecondGroupColumnName(secondGroup);
                CustomField customField = customFieldService.getById(secondGroup);
                if (Objects.nonNull(customFieldService.getById(secondGroup))) {
                    List<RadioOptionVo> options = JSONUtil.toList(Optional.ofNullable(customField.getCheckBox()).orElse("[]"), RadioOptionVo.class);
                    options.forEach(i -> {
                        List<Integer> missionIds = customFieldService.searchCustomField(Collections.singletonMap(customField.getId(), i.getValue()), ObjectType.mission.getCode());
                        mergeSearchResult.setMissionIds(missionIds);
                        long total = missionService.getGroupCountVo(mergeSearchResult,isH5);
                        typeCountData.add(new GroupCountVo().setOptionNum(total).setOptionName(i.getValue()).setOptionValue(i.getValue()).setTypeName(customField.getChineseName()));
                    });
                }
            }
        }
        return typeCountData;
    }

    //获取符合条件的任务数量
    public long getGroupCountVo(H5MissionListQuery query,boolean isH5) {
        return this.baseMapper.getGroupCountVo(query,isH5);
    }

    // 判断自定义字段的所属模块
    public void judgeCustomModel(Map<Integer, String> customFieldMap, MissionListVo voParam) {
        //区分所属自定义字段
        Set<Integer> customFieldIds = customFieldMap.keySet();
        Map<String, List<CustomField>> customFieldGroup = customFieldService.listByIds(customFieldIds).stream().collect(Collectors.groupingBy(CustomField::getFieldAscription));
        List<CustomField> workOrderCustomFields = customFieldGroup.get(ObjectType.workOrder.getCode());
        List<CustomField> processCustomFields = customFieldGroup.get(ObjectType.processes.getCode());
        if (!CollectionUtils.isEmpty(processCustomFields)) {
            HashMap<Integer, String> missionMap = new HashMap<>(processCustomFields.size());
            processCustomFields.forEach(i -> missionMap.put(i.getId(), customFieldMap.get(i.getId())));
            List<Integer> includeIds = customFieldService.searchCustomField(missionMap, ObjectType.mission.getCode());
            voParam.setMissionIds(includeIds);
        }
        if (!CollectionUtils.isEmpty(workOrderCustomFields)) {
            HashMap<Integer, String> workOrderMap = new HashMap<>(workOrderCustomFields.size());
            workOrderCustomFields.forEach(i -> workOrderMap.put(i.getId(), customFieldMap.get(i.getId())));
            List<Integer> includeIds = customFieldService.searchCustomField(workOrderMap, ObjectType.workOrder.getCode());
            voParam.setWorkOrderIds(includeIds);
        }
    }
}
